package com.xingchi.unique.factory;

import org.springframework.data.redis.core.StringRedisTemplate;

import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

/**
 * redis生成工厂
 *
 * @author xingchi
 * @date 2023/3/10 18:34
 * @modified xingchi
 */
@SuppressWarnings("all")
public class RedisIdFactory {

    private final StringRedisTemplate stringRedisTemplate;

    /**
     * 开始时间，单位s
     */
    private static final long TIME_EPOCH = 1675282963L;

    /**
     * 序列号位数
     */
    private static final int SEQUENCE_BITS = 32;
    private static final String FORMAT = "yyyy:MM:dd";

    public RedisIdFactory(StringRedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }

    public Long nextId(String businessPrefix) {

        // 获取当前时间，并计算当前时间与起始时间的差值
        LocalDateTime now = LocalDateTime.now();
        long currentTime = now.toEpochSecond(ZoneOffset.UTC);
        long timestamp = currentTime - TIME_EPOCH;

        if (timestamp < 0) {
            throw new RuntimeException("时钟回拨，请调整系统时间！");
        }

        // 根据时间进行区分
        String date = now.format(DateTimeFormatter.ofPattern(FORMAT));
        long count = stringRedisTemplate.opsForValue().increment("id:" + businessPrefix + ":" + date);
        return timestamp << SEQUENCE_BITS | count;
    }

    public List<Long> nextIds(String bussinessPrefix, int count) {
        List<Long> result = new ArrayList<>();
        for (int i = 0; i < count; i++) {
            result.add(this.nextId(bussinessPrefix));
        }
        return result;
    }

}
